package com.quanyan.stadium.service.commonComponent.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.quanyan.club.entity.RespClubPlainInfo;
import com.quanyan.common.utils.ObjectUtil;
import com.quanyan.common.vo.Image;
import com.quanyan.stadium.biz.BizGameSystemDao;
import com.quanyan.stadium.biz.redis.GameCacheDao;
import com.quanyan.stadium.component.pushMsg.MsgPush;
import com.quanyan.stadium.constants.GameConstants;
import com.quanyan.stadium.entity.TbGameCommonParameter;
import com.quanyan.stadium.entity.TbGameEvent;
import com.quanyan.stadium.entity.TbGameRound;
import com.quanyan.stadium.entity.vo.*;
import com.quanyan.stadium.enums.GameTypeConfigEnum;
import com.quanyan.stadium.service.commonComponent.BaseService;
import com.quanyan.stadium.service.commonComponent.OfficialGameCache;
import com.quanyan.stadium.transfer.GameConfigTransfer;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.response.RespUserInfoDetail;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * @author xiaoxiao
 * @date 16/4/11-14:42
 */

@Service("officialGameCache")
public class OfficialGameCacheImpl implements OfficialGameCache {

    private final static Logger logger = LoggerFactory.getLogger(OfficialGameCacheImpl.class);

    @Autowired
    private BizGameSystemDao bizGameSystemDao;

    @Autowired
    private GameCacheDao gameCacheDao;

    @Autowired
    private BaseService baseService;


    @Value("${share.server.name}")
    private String shareServerName;

    @Autowired
    private GameConfigTransfer gameEventTransfer;


    @Override
    public GameEvent getGameEvent(Integer gameEventId) throws InvocationTargetException, IllegalAccessException {
        GameEvent gameEvent = gameCacheDao.getGameEventFromCache(gameEventId);
        if (gameEvent == null || gameEvent.getId() < 1) {
            TbGameEvent tbGameEvent = bizGameSystemDao.selectTbGameEvent(gameEventId);
            if (ObjectUtil.isObjectEmpty(tbGameEvent)) {
                return gameEvent;
            }

            gameEvent = new GameEvent();
            try{
                BeanUtils.copyProperties(gameEvent, tbGameEvent);
            }catch (Exception e) {
            }

            gameEvent.setPayTypeModel(gameEventTransfer.getPayTypeModelById(tbGameEvent.getPayType().intValue()));
            gameEvent.setGameSystem(gameEventTransfer.getGameSystemById(tbGameEvent.getGameSystemType().intValue()));
            gameEvent.setGameCategory(gameEventTransfer.getGameCategoryById(tbGameEvent.getGameCategoryType().intValue()));
            gameEvent.setGameGradeLevel(gameEventTransfer.getGameGradeLevelById(tbGameEvent.getCategoryId(), tbGameEvent.getGameGradeLevelType().intValue()));
            gameEvent.setCreateTime(tbGameEvent.getUpdateTime().getTime());
            gameEvent.setGameTeamType(tbGameEvent.getGameTeamType());
            gameEvent.setCurTime(new Date().getTime());
            GameTypeConfigEnum gameTypeConfigEnum = GameTypeConfigEnum.getSysConfigEnum(tbGameEvent.getGameEventType());
            gameEvent.setGameType(new GameType(gameTypeConfigEnum.getId(), gameTypeConfigEnum.getLabel()));
            if (tbGameEvent.getCurrentRoundId().intValue() == -1) {   //结束
                gameEvent.setIsEnd((byte) 1);
            }
            gameEvent.setCurrentTeamNum(tbGameEvent.getTeamLimitNum() - tbGameEvent.getInventoryLevel());
            //场馆
            gameEvent.setPlaceInfo(transferPlaceInfo(tbGameEvent));

            //比赛发布人
            RespUserInfoDetail userInfoDetail = baseService.queryUserMsg(tbGameEvent.getUid());

            //主办方
            GameEventHost gameEventHost = new GameEventHost();
            gameEventHost.setType(tbGameEvent.getType());
            gameEventHost.setHostName(tbGameEvent.getManagerName());
            gameEventHost.setManagerName(tbGameEvent.getManagerName());
            RespClubPlainInfo clubInfo = null;
            Image image = new Image();
            if (GameConstants.CLUB_CREATE == tbGameEvent.getType()) {
                gameEventHost.setClubId(tbGameEvent.getClubId());
                clubInfo = baseService.queryClubMsg(tbGameEvent.getClubId());
                if (null!=clubInfo && !StringUtils.isEmpty(clubInfo.getLogo())) {
                    image.setImageUrl(clubInfo.getLogo());
                }
                gameEventHost.setManagerName(userInfoDetail.getNickName());
            }else if (GameConstants.PERSONAL_CREATE == tbGameEvent.getType() && null != userInfoDetail){
                image.setImageUrl(userInfoDetail.getIcon());
                gameEventHost.setManagerName(userInfoDetail.getNickName());
            }
            if (StringUtils.isEmpty(image.getImageUrl())) {
                TbGameCommonParameter icon = baseService.queryTbGameCommonParameter(GameConstants.STADIUM_DEFAULT_GROUP_BASE_CONFIG_KEY,
                        GameConstants.BASE_CONFIG_KEY_OFFICIAL_HOST_ICON);
                image.setImageUrl(icon.getParameterValue());
            }
            gameEventHost.setImage(image);
            gameEventHost.setHostMobile(tbGameEvent.getManagerMobile());
            gameEvent.setGameEventHost(gameEventHost);

            
            //图像
            try{
                Gson gson = new Gson();
                gameEvent.setMultiMediaType(gson.fromJson(tbGameEvent.getMultiMedia(), MultiMedia.class));
            }catch (Exception e) {
                logger.error("缓存赛事,图像转换出错,当前赛事ID",gameEventId);
            }

            //分享信息
            if (gameEvent.getGameEventType().intValue() == GameTypeConfigEnum.CONFIG_GAME_EVENT_TYPE_PERSONAL.getId()) {
                TbGameCommonParameter tbGameCommonParameter = baseService.queryTbGameCommonParameter(GameConstants.STADIUM_DEFAULT_GROUP_PARAMETER_KEY,
                        MsgPush.GAME_OFFICIAL_EVENT_SHARE_MSG);
                TbGameCommonParameter tbGameCommonParameter1 = baseService.queryTbGameCommonParameter(GameConstants.STADIUM_DEFAULT_GROUP_PARAMETER_KEY,
                        MsgPush.GAME_OFFICIAL_EVENT_SHARE_URL);
                gameEvent.setShareMsg(MsgPush.msgUtils(tbGameCommonParameter.getParameterValue(), tbGameEvent.getName()));  //分享
                gameEvent.setShareUrl(shareServerName+tbGameCommonParameter1.getParameterValue());
            }else if (gameEvent.getGameEventType().intValue() == GameTypeConfigEnum.CONFIG_GAME_EVENT_TYPE_INTERNAL.getId()) {
                TbGameCommonParameter tbGameCommonParameter = baseService.queryTbGameCommonParameter(GameConstants.STADIUM_DEFAULT_GROUP_BASE_CONFIG_KEY,
                        MsgPush.GAME_SCENE_EVENT_INTERNAL_DETAIL_SHARE_URL);
                gameEvent.setShareUrl(shareServerName + tbGameCommonParameter.getParameterValue());  //分享
            }else{
                ;
            }


            //开始存放
            gameCacheDao.initGameEventToCache(gameEvent);
            logger.info("缓存赛事ID:{}到缓存", tbGameEvent.getId());
        }
        gameEvent.setCurTime(new Date().getTime());
        return gameEvent;
    }

    private PlaceInfo transferPlaceInfo(TbGameEvent tbGameEvent) {
        PlaceInfo placeInfo = new PlaceInfo();
        if (null != placeInfo.getPlaceId() && placeInfo.getPlaceId() > 0) {
            List<Integer> placeIds = new ArrayList<>();
            placeIds.add(tbGameEvent.getPlaceId());
            Map<Integer, PlaceInfo> placeMap = baseService.queryPlaceInfoMsgList(placeIds);
            placeInfo = placeMap.get(tbGameEvent.getPlaceId());
        }else {
            placeInfo.setAddress(tbGameEvent.getAddress());
            placeInfo.setLat(tbGameEvent.getLat());
            placeInfo.setLng(tbGameEvent.getLng());
        }
        return placeInfo;
    }

    @Override
    public void delGameEvent(Integer gameEventId) {
        gameCacheDao.delGameEventFromCache(gameEventId);
    }

    @Override
    public Map<Integer, GameEvent> queryGameEvent(List<Integer> gameEventIds) throws InvocationTargetException, IllegalAccessException {
        Map<Integer, GameEvent> result = new HashMap<>();
        if (null == gameEventIds || gameEventIds.size() < 1) {
            return result;
        }
        for (Integer temp : gameEventIds) {
            result.put(temp, this.getGameEvent(temp));
        }
        return result;
    }

    @Override
    public GameRound getGameRound(Integer gameRoundId) throws InvocationTargetException, IllegalAccessException {
        GameRound gameRound = gameCacheDao.getGameRoundFromCache(gameRoundId);
        if (gameRound == null || gameRound.getId() < 1) {
            gameRound = new GameRound();
            TbGameRound tbGameRound = bizGameSystemDao.selectTbGameRound(gameRoundId);
            TbGameEvent tbGameEvent = bizGameSystemDao.selectTbGameEvent(tbGameRound.getGameEventId());
            gameRound.setId(tbGameRound.getId());
            gameRound.setGameEvent(this.getGameEvent(tbGameRound.getGameEventId()));
            gameRound.setName(tbGameRound.getName());
            gameRound.setTimeLength(tbGameRound.getSingleTime());
            if (tbGameRound.getStartTime() != null){
                gameRound.setStartTime(tbGameRound.getStartTime().getTime());
            }
            if (tbGameRound.getEndTime() != null) {
                gameRound.setEndTime(tbGameRound.getEndTime().getTime());
            }
            gameRound.setRoundStatus(tbGameRound.getRoundStatus().intValue());
            gameRound.setIsEnd(tbGameRound.getIsEnd());
            gameRound.setIsGenerate(tbGameRound.getIsGenerate());
            gameRound.setJoinNum(tbGameRound.getCurrentTeamNum());
            gameRound.setRankNum(tbGameRound.getRankTeamNum());
            gameRound.setTeamGroup(tbGameEvent.getTeamGroupNum());
            //开始存放
            gameCacheDao.initGameRoundToCache(gameRound);
            logger.info("缓存轮次ID:{}到缓存",gameRoundId);
        }
        return gameRound;
    }

    @Override
    public void delGameRound(Integer gameRoundId) {
        gameCacheDao.delGameRoundFromCache(gameRoundId);
    }

    @Override
    public Map<Integer, GameRound> queryGameRound(List<Integer> gameRoundIds) throws InvocationTargetException, IllegalAccessException {
        Map<Integer, GameRound> result = new HashMap<>();
        if (null == gameRoundIds || gameRoundIds.size() < 1) {
            return result;
        }
        for (Integer temp : gameRoundIds) {
            result.put(temp, this.getGameRound(temp));
        }
        return result;
    }

    @Override
    public List<GameRound> queryGameRoundList(List<Integer> gameRoundIds) throws InvocationTargetException, IllegalAccessException {
        List<GameRound> result = new ArrayList<>();
        if (null == gameRoundIds || gameRoundIds.size() < 1) {
            return result;
        }
        for (Integer temp : gameRoundIds) {
            result.add(this.getGameRound(temp));
        }
        return result;
    }

    @Override
    public GameSchedule getGameSchedule(Integer gameScheduleId, Byte teamType) throws InvocationTargetException, IllegalAccessException {
        GameSchedule gameSchedule = gameCacheDao.getGameScheduleFromCache(gameScheduleId);
        if (gameSchedule == null || gameSchedule.getId() < 1) {
            gameSchedule = new GameSchedule();
            List<VDefinedGameSchedule> definedGameSchedules = bizGameSystemDao.selectVDefinedGameScheduleById(gameScheduleId);
            if (null == definedGameSchedules || definedGameSchedules.size() <1) {
                return gameSchedule;
            }
            gameSchedule.setId(gameScheduleId);
            //组装
            try {
                gameSchedule = this.tbGameScheduleToGameSchedule(definedGameSchedules, gameSchedule, teamType);
            }catch (Exception e) {
                logger.error("tbGameScheduleToGameSchedule方法转换出错,当前赛程ID:{},错误原因:{}", gameScheduleId, e);
            }
            //开始存放
            gameCacheDao.initGameScheduleToCache(gameSchedule);
            logger.info("缓存初始化赛程ID:{}到缓存",gameSchedule.getId());
        }
        gameSchedule.setCurTime(new Date().getTime());
        return gameSchedule;
    }

    @Override
    public void delGameSchedule(Integer gameScheduleId) {
        gameCacheDao.delGameScheduleFromCache(gameScheduleId);
    }

    @Override
    public void updateGameSchedule(Integer gameScheduleId, Byte teamType) throws InvocationTargetException, IllegalAccessException {
        List<VDefinedGameSchedule> definedGameSchedules = bizGameSystemDao.selectVDefinedGameScheduleById(gameScheduleId);
        if (null == definedGameSchedules || definedGameSchedules.size() <1) {
            return;
        }
        GameSchedule gameSchedule = new GameSchedule();
        gameSchedule.setId(gameScheduleId);
        try {
            gameSchedule = this.tbGameScheduleToGameSchedule(definedGameSchedules, gameSchedule, teamType);
        }catch (Exception e) {
            logger.error("tbGameScheduleToGameSchedule方法转换出错,当前赛程ID:{},错误原因:{}", gameScheduleId, e);
        }
        gameCacheDao.initGameScheduleToCache(gameSchedule);
        logger.info("缓存更新赛程ID:{}到缓存", gameSchedule.getId());
    }

    @Override
    public Map<Integer, GameSchedule> queryGameSchedule(List<Integer> gameScheduleIds,  Byte temType) throws InvocationTargetException, IllegalAccessException {
        Map<Integer, GameSchedule> result = new HashMap<>();
        if (null == gameScheduleIds || gameScheduleIds.size() < 1) {
            return result;
        }
        for (Integer temp : gameScheduleIds) {
            result.put(temp, this.getGameSchedule(temp, temType));
        }
        return result;
    }

    @Override
    public List<GameSchedule> queryGameScheduleList(List<Integer> gameScheduleIds, Byte temType) throws InvocationTargetException, IllegalAccessException {
        List<GameSchedule> result = new ArrayList<>();
        if (null == gameScheduleIds || gameScheduleIds.size() < 1) {
            return result;
        }
        for (Integer temp : gameScheduleIds) {
            result.add(this.getGameSchedule(temp, temType));
        }
        return result;
    }

    @Override
    public GameEventConfig getGameEventConfig(int type) {
        return gameCacheDao.getGameEventConfig(type);
    }

    @Override
    public void intiGameEventConfig(GameEventConfig gameEventConfig, int type) {
        gameCacheDao.initGameEventConfig(gameEventConfig, type);
    }

    @Override
    public void delGameEventConfig(int type) {
        gameCacheDao.delGameEventConfig(type);
    }

    @Override
    public ClubGameEventConfig getClubGameEventConfig() {
        return gameCacheDao.getClubGameEventConfig();
    }

    @Override
    public void initClubGameEventConfig(ClubGameEventConfig clubGameEventConfig) {
        gameCacheDao.initClubGameEventConfig(clubGameEventConfig);
    }

    @Override
    public void deleteClubGameEventConfig() {

        try{
            gameCacheDao.deleteClubGameEventConfig();
        } catch (Exception e) {
            logger.error("deleteClubGameEventConfig exception:", e);
        }
    }

    @Override
    public void updateBlackUser(int uid) {
        gameCacheDao.updateBlackUser(uid);
    }

    @Override
    public List<Integer> queryBlackUser() {
        return gameCacheDao.queryBlackUser();
    }

    @Override
    public void deleteAllBlackUser() {
        gameCacheDao.deleteAllBlackUser();
    }

    @Override
    public void deleteOneBlackUser(int uid) {
        gameCacheDao.deleteOneBlackUser(uid);
    }
    /**
     * 转换方法,组装GameSchedule
     *
     * */
    private GameSchedule tbGameScheduleToGameSchedule(List<VDefinedGameSchedule> definedGameSchedules, GameSchedule gameSchedule, Byte teamType) throws InvocationTargetException, IllegalAccessException {
        //获取场地信息
        Set<Integer> gameTeamIdSet = new HashSet<>();
        Set<Integer> placeUnitIdSet = new HashSet<>();
        List<Integer> uIds = new ArrayList<>();
        List<Integer> clubIds = new ArrayList<>();
        for (VDefinedGameSchedule vDefinedGameSchedule : definedGameSchedules) {
            gameTeamIdSet.add(vDefinedGameSchedule.getEventTeamId());
            if (null != vDefinedGameSchedule.getPlaceUnitId()) {
                placeUnitIdSet.add(vDefinedGameSchedule.getPlaceUnitId());
            }
            if (GameConstants.TEAM_TYPE_PERSON == teamType.byteValue()) {
                uIds.add(vDefinedGameSchedule.getUid());
            }else if (GameConstants.TEAM_TYPE_CLUB == teamType.byteValue()){
                clubIds.add(vDefinedGameSchedule.getClubId());
            }else {
            }
        }
        if (uIds!=null&&uIds.size()>0&&clubIds!=null&&clubIds.size()>0) {
            return gameSchedule;
        }

        Map<Integer, RespClubPlainInfo> mapClubIdMap = new HashMap<>();
        Map<Integer, RespUserInfoBase> mapUidMap = new HashMap<>();

        if (clubIds.size()>0) {
            mapClubIdMap = baseService.queryClubMsg(clubIds);
        }
        if (uIds.size() > 0) {
            mapUidMap = baseService.queryUserMsg(uIds);
        }

        Map<Integer, PlaceUnitInfo> placeUnitInfoMap = baseService.queryPlaceUnitInfoMsgList(new ArrayList<Integer>(placeUnitIdSet));
        Map<Integer, PlaceInfo> placeInfoMap = new HashMap<>();
        GameTeam gameTeam = new GameTeam();
        GameTeam gameTeam1 = new GameTeam();
        List<User> users1 = new ArrayList<>();
        List<User> users2 = new ArrayList<>();
        Map<Integer, Integer> locationMap = new HashMap<>();
        Map<Integer, Integer> locationMap1 = new HashMap<>();
        for (VDefinedGameSchedule vDefinedGameSchedule : definedGameSchedules) {
            if (null != vDefinedGameSchedule.getFinalScore()) {
                gameSchedule.setScore(vDefinedGameSchedule.getFinalScore());
            }
            if (null != vDefinedGameSchedule.getPlaceUnitId()) {
                PlaceUnitInfo placeUnitInfo = placeUnitInfoMap.get(vDefinedGameSchedule.getPlaceUnitId());
                if (null==placeInfoMap || null == placeInfoMap.get(placeUnitInfo.getPlaceId())) {
                    List<Integer> ids = new ArrayList<>();
                    ids.add(placeUnitInfo.getPlaceId());
                    Map<Integer, PlaceInfo> temp = baseService.queryPlaceInfoMsgList(ids);
                    if (null!=temp && temp.size()>0) {
                        placeInfoMap.putAll(temp);
                    }
                }
                if (null!=placeInfoMap && null != placeInfoMap.get(placeUnitInfo.getPlaceId())) {
                    placeUnitInfo.setName(placeInfoMap.get(placeUnitInfo.getPlaceId()).getName());
                }
                gameSchedule.setPlaceUnitInfo(placeUnitInfo);
            }
            if (null != vDefinedGameSchedule.getStatus()) {
                gameSchedule.setRecordStatus(vDefinedGameSchedule.getStatus());
            }

            if (null != vDefinedGameSchedule.getStartTime()) {
                gameSchedule.setStartTime(vDefinedGameSchedule.getStartTime().getTime());
            }
            if (null != vDefinedGameSchedule.getEndTime()) {
                gameSchedule.setEndTime(vDefinedGameSchedule.getEndTime().getTime());
            }
            gameSchedule.setIsWin(vDefinedGameSchedule.getIsWin());

            gameSchedule.setRoundId(vDefinedGameSchedule.getGameRoundId());
            gameSchedule.setGroup(vDefinedGameSchedule.getGroup());    //获取分组,适用于混合赛
            gameTeam.setType(teamType);
            gameTeam1.setType(teamType);

            List<Integer> locationList = new Gson().<List<Integer>>fromJson(vDefinedGameSchedule.getTeamListIndex(), new TypeToken<List<Integer>>() {
            }.getType());
            if (GameConstants.TEAM_TYPE_CLUB.byteValue() == teamType) {
                if (vDefinedGameSchedule.getType() == 0) {
                    gameTeam.setId(vDefinedGameSchedule.getEventTeamId());
                    if (null !=  mapClubIdMap && null !=  mapClubIdMap.get(vDefinedGameSchedule.getClubId()) && mapClubIdMap.get(vDefinedGameSchedule.getClubId()).getClubId()>0) {
                        Club club = new Club();
                        BeanUtils.copyProperties(club,  mapClubIdMap.get(vDefinedGameSchedule.getClubId()));
                        gameTeam.setClub(club);
                    }
                }else if (vDefinedGameSchedule.getType() == 1) {
                    gameTeam1.setId(vDefinedGameSchedule.getEventTeamId());
                    if (null !=  mapClubIdMap && null !=  mapClubIdMap.get(vDefinedGameSchedule.getClubId()) && mapClubIdMap.get(vDefinedGameSchedule.getClubId()).getClubId()>0) {
                        Club club = new Club();
                        BeanUtils.copyProperties(club,  mapClubIdMap.get(vDefinedGameSchedule.getClubId()));
                        gameTeam1.setClub(club);
                    }
                }
            }else if (GameConstants.TEAM_TYPE_PERSON.byteValue() == teamType) {
                if (vDefinedGameSchedule.getType() == 0) {
                    gameTeam.setId(vDefinedGameSchedule.getEventTeamId());
                    if (null !=  mapUidMap && null !=  mapUidMap.get(vDefinedGameSchedule.getUid()) && null!=mapUidMap.get(vDefinedGameSchedule.getUid())) {
                        User user = new User();
                        BeanUtils.copyProperties(user,  mapUidMap.get(vDefinedGameSchedule.getUid()));
                        users1.add(user);

                        if (CollectionUtils.isNotEmpty(locationList)) {
                            locationMap.put(user.getUid(), 1+locationList.indexOf(vDefinedGameSchedule.getEventTeamId()));
                        }
                    }
                }else if (null !=  mapUidMap && vDefinedGameSchedule.getType() == 1) {
                    gameTeam1.setId(vDefinedGameSchedule.getEventTeamId());
                    if (null !=  mapUidMap.get(vDefinedGameSchedule.getUid()) && null!=mapUidMap.get(vDefinedGameSchedule.getUid())) {
                        User user = new User();
                        BeanUtils.copyProperties(user,  mapUidMap.get(vDefinedGameSchedule.getUid()));
                        users2.add(user);

                        if (CollectionUtils.isNotEmpty(locationList)) {
                            locationMap1.put(user.getUid(), 1+locationList.indexOf(vDefinedGameSchedule.getEventTeamId()));
                        }
                    }
                }
            }else {
            }
        }
        gameTeam.setLocation(locationMap);
        gameTeam.setUserList(users1);
        gameTeam1.setLocation(locationMap1);
        gameTeam1.setUserList(users2);
        gameSchedule.setHomeGameTeam(gameTeam);
        if (!(ObjectUtils.isEmpty(gameTeam1.getUserList()) && ObjectUtils.isEmpty(gameTeam1.getClub()))) {
            gameSchedule.setAwayGameTeam(gameTeam1);
        }
        gameSchedule.setCurTime(new Date().getTime());
        return gameSchedule;
    }
}
